/**
 *	@file	pgear_sky.c
 *	@brief	空を飛ぶ　システムマップ
 *	@author	Miyuki Iwasawa
 *	@date	07.06.20
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/brightness.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/wipe.h"
#include "system/buflen.h"
#include "gflib/touchpanel.h"
#include "field/field_matrix.h"
#include "field/field_place_name.h"
#include "application/app_tool.h"
#include "application/pokegear.h"
#include "msgdata/msg.naix"
#include "fielddata/maptable/zone_id.h"

#include "../pgear_sys.h"
#include "../pgear_frm.h"
#include "../pgear_act.h"
#include "pgmap_sys.h"
#include "pgsky_bg.h"
#include "pgmap_sub.h"
#include "pgmap_key.h"
#include "pgmap_mk.h"
#include "msgdata/msg_pgmap_guide.h"

//データテーブル
#include "mzone_param.h"
#include "town_param.h"

#include "system/pm_overlay.h"
FS_EXTERN_OVERLAY(pgear_frm);
FS_EXTERN_OVERLAY(field_revenge);

//プロトタイプ宣言　グローバル
//================================================================
///オーバーレイプロセス定義
PROC_RESULT PGearSkyProc_Init( PROC *proc,int *seq);
PROC_RESULT PGearSkyProc_Main( PROC *proc,int *seq);
PROC_RESULT PGearSkyProc_End( PROC *proc,int *seq);

//プロトタイプ宣言　ローカル
//================================================================
static void skysub_InitDataSet(PGMAP_SYS_WORK* wk);
static void skysub_LastDataSet(PGMAP_SYS_WORK* wk);
static int skyseq_AppInit(PGMAP_SYS_WORK* wk);
static int skyseq_AppMain(PGMAP_SYS_WORK* wk);
static int skyseq_AppEnd(PGMAP_SYS_WORK* wk);
static int skyseq_JumpSelect(PGMAP_SYS_WORK* wk);
static int skyseq_AllFadeIn(PGMAP_SYS_WORK* wk);
static int skyseq_AllFadeOut(PGMAP_SYS_WORK* wk);

/**
 *	@brief	空を飛ぶ マッププロセス初期化
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return	処理状況
 */
PROC_RESULT PGearSkyProc_Init( PROC *proc,int *seq)
{
	PGMAP_SYS_WORK *wk = NULL;
	PGEAR_PARAM * param = (PGEAR_PARAM*)PROC_GetParentWork(proc);

	Overlay_Load( FS_OVERLAY_ID( pgear_frm ), OVERLAY_LOAD_NOT_SYNCHRONIZE );
	Overlay_Load( FS_OVERLAY_ID( field_revenge ), OVERLAY_LOAD_NOT_SYNCHRONIZE );

	//ワークエリア取得
	HeapStatePush();

	//ヒープ作成
	sys_CreateHeap(HEAPID_BASE_APP,HEAPID_PGEAR_APP,0x40000);

	wk = PROC_AllocWork( proc,sizeof(PGMAP_SYS_WORK),HEAPID_PGEAR_APP);
	memset(wk,0,sizeof(PGMAP_SYS_WORK));

	wk->sys = sys_AllocMemory(HEAPID_PGEAR_APP, sizeof(PGEAR_SYS_WORK));
	memset(wk->sys,0,sizeof(PGEAR_SYS_WORK));

	wk->heapID = HEAPID_PGEAR_APP;
	wk->sys->heapID = HEAPID_PGEAR_APP;

	wk->sys->param = param;
	//ポケギアセーブデータポインタ取得
	wk->sys->save = wk->sys->param->save;
	wk->sys->pg_save = SaveData_GetPGearSave(wk->sys->save);
	wk->sys->ev_save = SaveData_GetEventWork(wk->sys->save);
	wk->sys->config_save = SaveData_GetConfig(wk->sys->save);
	wk->sys->my_save = SaveData_GetMyStatus(wk->sys->save);


	//引継ぎデータの初期化
	skysub_InitDataSet(wk);

	//サウンド引継ぎ設定
//	Snd_DataSetByScene( SND_SCENE_SUB_TOWNMAP, 0, 0 );

	wk->pMZoneTbl = PGearMap_MapZoneParam;
	wk->zTblMax = PGMAP_ZONE_MAX;
	return PROC_RES_FINISH;
}

/**
 *	@brief	空を飛ぶ　マッププロセスメイン
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return 処理状況
 */
PROC_RESULT PGearSkyProc_Main(PROC* proc,int *seq)
{
	PGMAP_SYS_WORK* wk = PROC_GetWork(proc);

	switch(*seq){
	case PGMAP_SEQ_INIT:
		*seq = skyseq_AppInit(wk);
		break;
	case PGMAP_SEQ_MAIN:
		*seq = skyseq_AppMain(wk);
		break;
	case PGMAP_SEQ_END:
		*seq = skyseq_AppEnd(wk);
		break;
	case PGMAP_SEQ_JUMP_SELECT:
		*seq = skyseq_JumpSelect(wk);
		break;
	case PGMAP_SEQ_ALL_FADEIN:
		*seq = skyseq_AllFadeIn(wk);
		break;
	case PGMAP_SEQ_ALL_FADEOUT:
		*seq = skyseq_AllFadeOut(wk);
		break;
	case PGMAP_SEQ_APP_EXIT:
		return PROC_RES_FINISH;
	}
	return PROC_RES_CONTINUE;
}

/**
 *	@brief	空を飛ぶ　メインプロセス終了
 *
 *	@param	proc	プロセスデータ
 *	@param	seq		シーケンス
 *
 *	@return 処理状況
 */
PROC_RESULT PGearSkyProc_End(PROC* proc,int* seq)
{
	int heapID = 0;
	PGMAP_SYS_WORK* wk = PROC_GetWork(proc);

	//セーブデータ反映
	skysub_LastDataSet(wk);

	//ゾーンデータ解放
	FreeFMZ(wk->pZone);

	if(wk->sys->next_mode != PG_NEXT_WORD){
		//アプリケーション初回呼び出し終了フラグを立てておく
		wk->sys->call_end = 1;
	}

	//ワークエリア開放
	MI_CpuClear8(wk->sys,sizeof(PGEAR_SYS_WORK));
	sys_FreeMemoryEz(wk->sys);

	heapID = wk->heapID;
	PROC_FreeWork(proc);

	HeapStatePop();
	HeapStateCheck(heapID);
	sys_DeleteHeap(heapID);

	Overlay_UnloadID( FS_OVERLAY_ID( field_revenge ) );
	Overlay_UnloadID( FS_OVERLAY_ID( pgear_frm ) );

	return PROC_RES_FINISH;
}

/**
 *	@brief	空を飛ぶマップ　初期データ設定
 */
static void skysub_InitDataSet(PGMAP_SYS_WORK* wk)
{
	static const u16 scrLimBlock[]={
		MAPS_LIM_BR0,MAPS_LIM_BR1,MAPS_LIM_BR2,
	};

	//システムにアプリワークポインタを通知
	wk->sys->app_vwork = (void*)wk;

	//システムにSysKey2AppKey描画の切替関数ポインタを通知
	wk->sys->key_mode = wk->sys->param->key_mode;
	wk->map_mode = wk->sys->param->mode+1;

	wk->sys->to_akey_func = PGMapSub_ToKeyChangeMap;
	wk->sys->to_touch_func = PGMapSub_ToTouchChangeMap;

	//マーカーセーブデータを取得
	PGMapMk_GetSaveData(wk);

	wk->keymode = 0;
	wk->keymode_st = 0;
	wk->f_open = PGearSv_GetMapOpenLevel(wk->sys->pg_save);

#ifdef PM_DEBUG
	wk->debug_f = wk->sys->param->debug_f;
	if(wk->debug_f){
		wk->f_open = 2;
	}
#endif

	//ゾーンリソース取得
	wk->pZone = InitFMZ(wk->heapID);

	//電話セーブデータ取得
	wk->tel_sv = SaveData_GetPMTelSave(wk->sys->save);

	//電話帳データ取得
	wk->tel_book = PMTelBookData_AllocAll(wk->heapID);
	wk->tel_number = PGearSv_GetTelBook(wk->sys->pg_save,wk->heapID);
	//登録数取得
	wk->tel_nummax = PGearSv_GetTelBookEntryNum(wk->sys->pg_save);

	//自機の初期位置
#if 0
	wk->player_org.x = wk->sys->param->player_x/MBLOCK_GRID;
	wk->player_org.z = wk->sys->param->player_z/MBLOCK_GRID;
	wk->player.x = wk->player_org.x;
	wk->player.z = wk->player_org.z+PGMAP_MATOFS_Z;
	wk->player.zone = wk->sys->param->player_zone;
	wk->player.val = wk->sys->param->player_sex;
#else
	wk->player.x = wk->sys->param->tmap_gx;
	wk->player.z = wk->sys->param->tmap_gz+PGMAP_MATOFS_Z;
	wk->player.zone = wk->sys->param->player_zone;
	wk->player.val = wk->sys->param->player_sex;
#endif
	//ターゲットの初期ブロック位置
	wk->cTarget.x = wk->sys->param->tmap_gx;	//wk->player.x;
	wk->cTarget.z = wk->sys->param->tmap_gz+PGMAP_MATOFS_Z;	//wk->player.z;

	//スクロールリミット設定
	wk->scrl.lim_bl = MAPS_LIM_BL;
	wk->scrl.lim_bu = MAPS_LIM_BU;
	wk->scrl.lim_br = scrLimBlock[wk->f_open];
	wk->scrl.lim_bd = MAPS_LIM_BD;

	wk->mapf_lsiz = SMAPF_L_SIZ;
	wk->mapf_usiz = SMAPF_U_SIZ;
	wk->maps_hdef = SPGM_MAPS_HDEF;
	wk->maps_wdef = -(SMAPF_L_SIZ-8);

	//サファリ他の到着フラグ取得
	wk->arrive_safari = TRUE;	//SysFlag_ArriveGet(wk->sys->ev_save,FLAG_ARRIVE_R47);	//強制オープン090629
	wk->arrive_t24 = SysFlag_ArriveGet(wk->sys->ev_save,FLAG_ARRIVE_T24);

	//自分がいる地方を取得
	wk->my_local = PGFrame_GetLocalArea(wk->sys);
}

/**
 *	@brief	空を飛ぶマップ　終了時データ書き戻し設定
 */
static void skysub_LastDataSet(PGMAP_SYS_WORK* wk)
{
	sys_FreeMemoryEz(wk->tel_number);
	PMTelBookData_Free(wk->tel_book);

	//関数ポインタクリア
	wk->sys->to_akey_func = NULL;
	wk->sys->to_touch_func = NULL;

	//マーカーデータ書き戻し
//	PGMapMk_SetSaveData(wk);

	//マップの拡縮状態書き戻し
//	PGearSv_SetMapAff(wk->sys->pg_save,wk->f_affine);
}

/**
 *	@brief	空を飛ぶマップ　シーケンス初期化
 */
static int skyseq_AppInit(PGMAP_SYS_WORK* wk)
{
	if(!PGSky_AppInit(wk)){
		return PGMAP_SEQ_INIT;
	}
	return PGMAP_SEQ_ALL_FADEIN;
}

/**
 *	@brief	空を飛ぶマップ　メインシーケンス
 */
static int skyseq_AppMain(PGMAP_SYS_WORK* wk)
{
	int ret = PG_NEXT_NULL;
	int zone,touch_f = FALSE;

	//キーorタッチ操作の切替取得
	if(wk->touch_st == 0){
		ret = PGSkyKey_TouchContMap(wk,&touch_f);
	}else{
		ret = PGMapKey_TouchContMapScrl(wk);
		touch_f = TRUE;
	}
	if(touch_f){
		wk->sys->key_mode = APP_KTST_TOUCH;

		wk->sys->next_mode = ret;
		switch(ret){
		case PG_NEXT_APP_SEQ:
			return PGMAP_SEQ_JUMP_SELECT;
		case PG_NEXT_EXIT:
			return PGMAP_SEQ_ALL_FADEOUT;
		case PG_NEXT_NULL:
		default:
			break;
		}
		return PGMAP_SEQ_MAIN;
	}

	if(sys.trg & PAD_BUTTON_KTST_CHG){
		wk->sys->key_mode = APP_KTST_KEY;
	}
	ret = PGSkyKey_ContMap(wk);

	wk->sys->next_mode = ret;
	switch(ret){
	case PG_NEXT_APP_SEQ:
		return PGMAP_SEQ_JUMP_SELECT;
	case PG_NEXT_EXIT:
		return PGMAP_SEQ_ALL_FADEOUT;
	case PG_NEXT_NULL:
	default:
		PGMapKey_UpdateCursor(wk);
		return PGMAP_SEQ_MAIN;
	}
}

/**
 *	@brief	空を飛ぶマップ　シーケンス終了
 */
static int skyseq_AppEnd(PGMAP_SYS_WORK* wk)
{
	if(!PGSky_AppEnd(wk)){
		return PGMAP_SEQ_END;
	}

	//リターンパラメータをシステムに返す
	wk->sys->ret.map = wk->ret;
	return PGMAP_SEQ_APP_EXIT;
}

/**
 *	@brief	空を飛ぶマップ　選択
 */
static int skyseq_JumpSelect(PGMAP_SYS_WORK* wk)
{
	return PGSky_JumpSelect(wk);
}

/**
 *	@brief	空を飛ぶマップ　フェードイン
 */
static int skyseq_AllFadeIn(PGMAP_SYS_WORK* wk)
{
	int i;

	switch(wk->main_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEIN,
				WIPE_TYPE_FADEIN,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		//BGの表示をOnにする
		for(i = 0;i < 8;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME0_M+i,VISIBLE_ON);
		}
		GF_Disp_GX_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_ON);
		GF_Disp_GXS_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_ON);

		wk->main_seq++;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		wk->main_seq = 0;
		return PGMAP_SEQ_MAIN;
	}

	return PGMAP_SEQ_ALL_FADEIN;
}
/**
 *	@brief	空を飛ぶマップ　フェードアウト
 */
static int skyseq_AllFadeOut(PGMAP_SYS_WORK* wk)
{
	int i;
	switch(wk->main_seq){
	case 0:
		WIPE_SYS_Start(WIPE_PATTERN_WMS,
				WIPE_TYPE_FADEOUT,
				WIPE_TYPE_FADEOUT,0x0000,COMM_BRIGHTNESS_SYNC,1,wk->heapID
				);
		wk->main_seq++;
		break;
	case 1:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		//BGの表示をOffにする
		for(i = 0;i < 8;i++){
			GF_BGL_VisibleSet(GF_BGL_FRAME0_M+i,VISIBLE_OFF);
		}
		GF_Disp_GX_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_OFF);
		GF_Disp_GXS_VisibleControl(GX_PLANEMASK_OBJ,VISIBLE_OFF);
		wk->main_seq = 0;
		return PGMAP_SEQ_END;
	}

	return PGMAP_SEQ_ALL_FADEOUT;
}
